#include <stdio.h>


#define __func_align    __attribute__ ((aligned (0x100)))

#define __pr_mesg(fcaller) \
    printf("%s return to %s@%p, return addr: %p, delta: 0x%X\n", \
            __func__, #fcaller, fcaller, __builtin_return_address(0), \
            ((unsigned long)__builtin_return_address(0) - (unsigned long)fcaller))

#define __ret_addr(level) \
	printf("%s return level %d: %p\n", \
			__func__, level, __builtin_return_address(level))

#define __func(caller, cur, callee)    \
    static void __func_align foo##cur(void)  \
    {                   \
        int i = 0x55;   \
        foo##callee();  \
        __pr_mesg(foo##caller); \
    }

static void foo0(void);
static void foo1(void);
static void foo2(void);
static void foo3(void);
static void foo4(void);
static void foo5(void);
static void foo6(void);
static void foo7(void);
static void foo8(void);

static void __func_align foo0(void)
{
    __ret_addr(0);
    __ret_addr(1);
    __ret_addr(2);
    __ret_addr(3);
    __ret_addr(4);
    __ret_addr(5);
    __ret_addr(6);
    __ret_addr(7);
    __ret_addr(8);
    __pr_mesg(foo1); 
}


__func(2, 1, 0)
__func(3, 2, 1)
__func(4, 3, 2)
__func(5, 4, 3)
__func(6, 5, 4)
__func(7, 6, 5)
__func(8, 7, 6)

int main(void);

static void __func_align foo8(void)
{   int i;         
    i = 0x55; 
    foo7();  
    __pr_mesg(main);
}

int main(void)
{
    foo8();
    return 0;
}


